package club.mrxiao.gps.socket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * GPS服务端线程
 * @author  xiaoyu
 *
 */
@Slf4j
@Component
public class GpsService{
    private static final String SOCKET_CLOSED = "Socket closed";
    private ServerSocket serverSocket = null;  
    private Boolean sign = true;
    public static final List<GpsDataDispose> GPS_DATA_DISPOSE_LIST = new ArrayList<>();

    /**
     * 启动socket监听
     * @param port
     * @param gpsExecutor
     */
    public void startSocketServer(Integer port,ThreadPoolTaskExecutor gpsExecutor){
        try {
            if(null == serverSocket){
                this.serverSocket = new ServerSocket(port);
                log.info("serverSocket启动成功,端口：{},最大连接数：{}",port,gpsExecutor.getMaxPoolSize());
                while(sign){
                    try {
                        Socket socket = serverSocket.accept();
                        if(gpsExecutor.getMaxPoolSize() > GPS_DATA_DISPOSE_LIST.size()){
                            if(null != socket && !socket.isClosed()){
                                socket.setSoTimeout(60000);
                                GpsDataDispose gpsDataDispose = new GpsDataDispose(socket);
                                gpsExecutor.execute(gpsDataDispose);
                                GPS_DATA_DISPOSE_LIST.add(gpsDataDispose);
                                log.info("socket连接数：{},最大连接数：{}",GPS_DATA_DISPOSE_LIST.size(),gpsExecutor.getMaxPoolSize());
                            }
                        }else{
                            log.error("socket连接数超出最大连接数");
                            socket.close();
                        }
                    }catch (Exception e) {
                        sign = false;
                        if(SOCKET_CLOSED.equals(e.getMessage())){
                            log.info("serverSocket关闭");
                        }else{
                            log.error("socket监听出错",e);
                            this.closeSocketServer();
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("GpsService创建socket服务出错,端口"+port+"被其他程序使用",e);
            this.closeSocketServer();
        }
    }

    /**
     * 关闭
     */
    public void closeSocketServer(){  
       try {  
            if(null!=serverSocket && !serverSocket.isClosed()){
            	sign = false;
            	serverSocket.close();  
            }
       } catch (IOException e) {  
        e.printStackTrace();  
       }  
     } 
}